<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    
    <title>2.1.4. 矩阵分解 &#8212; FunRec 推荐系统 0.0.1 documentation</title>

    <link rel="stylesheet" href="../../_static/material-design-lite-1.3.0/material.blue-deep_orange.min.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/sphinx_materialdesign_theme.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/fontawesome/all.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/fonts.css" type="text/css" />
    <link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
    <link rel="stylesheet" type="text/css" href="../../_static/basic.css" />
    <link rel="stylesheet" type="text/css" href="../../_static/d2l.css" />
    <script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
    <script src="../../_static/jquery.js"></script>
    <script src="../../_static/underscore.js"></script>
    <script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
    <script src="../../_static/doctools.js"></script>
    <script src="../../_static/sphinx_highlight.js"></script>
    <script src="../../_static/d2l.js"></script>
    <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
    <link rel="index" title="Index" href="../../genindex.html" />
    <link rel="search" title="Search" href="../../search.html" />
    <link rel="next" title="2.1.5. 总结" href="5.summary.html" />
    <link rel="prev" title="2.1.3. Swing 算法" href="3.swing.html" /> 
  </head>
<body>
    <div class="mdl-layout mdl-js-layout mdl-layout--fixed-header mdl-layout--fixed-drawer"><header class="mdl-layout__header mdl-layout__header--waterfall ">
    <div class="mdl-layout__header-row">
        
        <nav class="mdl-navigation breadcrumb">
            <a class="mdl-navigation__link" href="../index.html"><span class="section-number">2. </span>召回模型</a><i class="material-icons">navigate_next</i>
            <a class="mdl-navigation__link" href="index.html"><span class="section-number">2.1. </span>协同过滤</a><i class="material-icons">navigate_next</i>
            <a class="mdl-navigation__link is-active"><span class="section-number">2.1.4. </span>矩阵分解</a>
        </nav>
        <div class="mdl-layout-spacer"></div>
        <nav class="mdl-navigation">
        
<form class="form-inline pull-sm-right" action="../../search.html" method="get">
      <div class="mdl-textfield mdl-js-textfield mdl-textfield--expandable mdl-textfield--floating-label mdl-textfield--align-right">
        <label id="quick-search-icon" class="mdl-button mdl-js-button mdl-button--icon"  for="waterfall-exp">
          <i class="material-icons">search</i>
        </label>
        <div class="mdl-textfield__expandable-holder">
          <input class="mdl-textfield__input" type="text" name="q"  id="waterfall-exp" placeholder="Search" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </div>
      </div>
      <div class="mdl-tooltip" data-mdl-for="quick-search-icon">
      Quick search
      </div>
</form>
        
<a id="button-show-source"
    class="mdl-button mdl-js-button mdl-button--icon"
    href="../../_sources/chapter_1_retrieval/1.cf/4.mf.rst.txt" rel="nofollow">
  <i class="material-icons">code</i>
</a>
<div class="mdl-tooltip" data-mdl-for="button-show-source">
Show Source
</div>
        </nav>
    </div>
    <div class="mdl-layout__header-row header-links">
      <div class="mdl-layout-spacer"></div>
      <nav class="mdl-navigation">
          
              <a  class="mdl-navigation__link" href="https://funrec-notebooks.s3.eu-west-3.amazonaws.com/fun-rec.zip">
                  <i class="fas fa-download"></i>
                  Jupyter 记事本
              </a>
          
              <a  class="mdl-navigation__link" href="https://github.com/datawhalechina/fun-rec">
                  <i class="fab fa-github"></i>
                  GitHub
              </a>
      </nav>
    </div>
</header><header class="mdl-layout__drawer">
    
          <!-- Title -->
      <span class="mdl-layout-title">
          <a class="title" href="../../index.html">
              <span class="title-text">
                  FunRec 推荐系统
              </span>
          </a>
      </span>
    
    
      <div class="globaltoc">
        <span class="mdl-layout-title toc">Table Of Contents</span>
        
        
            
            <nav class="mdl-navigation">
                <ul>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_preface/index.html">前言</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_installation/index.html">安装</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_notation/index.html">符号</a></li>
</ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../chapter_0_introduction/index.html">1. 推荐系统概述</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_0_introduction/1.intro.html">1.1. 推荐系统是什么？</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_0_introduction/2.outline.html">1.2. 本书概览</a></li>
</ul>
</li>
<li class="toctree-l1 current"><a class="reference internal" href="../index.html">2. 召回模型</a><ul class="current">
<li class="toctree-l2 current"><a class="reference internal" href="index.html">2.1. 协同过滤</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="1.usercf.html">2.1.1. 基于用户的协同过滤</a></li>
<li class="toctree-l3"><a class="reference internal" href="2.itemcf.html">2.1.2. 基于物品的协同过滤</a></li>
<li class="toctree-l3"><a class="reference internal" href="3.swing.html">2.1.3. Swing 算法</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">2.1.4. 矩阵分解</a></li>
<li class="toctree-l3"><a class="reference internal" href="5.summary.html">2.1.5. 总结</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../2.embedding/index.html">2.2. 向量召回</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../2.embedding/1.i2i.html">2.2.1. I2I召回</a></li>
<li class="toctree-l3"><a class="reference internal" href="../2.embedding/2.u2i.html">2.2.2. U2I召回</a></li>
<li class="toctree-l3"><a class="reference internal" href="../2.embedding/3.summary.html">2.2.3. 总结</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../3.sequence/index.html">2.3. 序列召回</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../3.sequence/1.user_interests.html">2.3.1. 深化用户兴趣表示</a></li>
<li class="toctree-l3"><a class="reference internal" href="../3.sequence/2.generateive_recall.html">2.3.2. 生成式召回方法</a></li>
<li class="toctree-l3"><a class="reference internal" href="../3.sequence/3.summary.html">2.3.3. 总结</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_2_ranking/index.html">3. 精排模型</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_2_ranking/1.wide_and_deep.html">3.1. 记忆与泛化</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_2_ranking/2.feature_crossing/index.html">3.2. 特征交叉</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/2.feature_crossing/1.second_order.html">3.2.1. 二阶特征交叉</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/2.feature_crossing/2.higher_order.html">3.2.2. 高阶特征交叉</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/2.feature_crossing/3.summary.html">3.2.3. 总结</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_2_ranking/3.sequence.html">3.3. 序列建模</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_2_ranking/4.multi_objective/index.html">3.4. 多目标建模</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/4.multi_objective/1.arch.html">3.4.1. 基础结构演进</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/4.multi_objective/2.dependency_modeling.html">3.4.2. 任务依赖建模</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/4.multi_objective/3.multi_loss_optim.html">3.4.3. 多目标损失融合</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/4.multi_objective/4.summary.html">3.4.4. 小结</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_2_ranking/5.multi_scenario/index.html">3.5. 多场景建模</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/5.multi_scenario/1.multi_tower.html">3.5.1. 多塔结构</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/5.multi_scenario/2.dynamic_weight.html">3.5.2. 动态权重建模</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/5.multi_scenario/3.summary.html">3.5.3. 小结</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_3_rerank/index.html">4. 重排模型</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_3_rerank/1.greedy.html">4.1. 基于贪心的重排</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_3_rerank/2.personalized.html">4.2. 基于个性化的重排</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_3_rerank/3.summary.html">4.3. 本章小结</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_4_trends/index.html">5. 难点及热点研究</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_4_trends/1.debias.html">5.1. 模型去偏</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_4_trends/2.cold_start.html">5.2. 冷启动问题</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_4_trends/3.generative.html">5.3. 生成式推荐</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_4_trends/4.summary.html">5.4. 本章小结</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_5_projects/index.html">6. 项目实践</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_5_projects/1.understanding.html">6.1. 赛题理解</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_5_projects/2.baseline.html">6.2. Baseline</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_5_projects/3.analysis.html">6.3. 数据分析</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_5_projects/4.recall.html">6.4. 多路召回</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_5_projects/5.feature_engineering.html">6.5. 特征工程</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_5_projects/6.ranking.html">6.6. 排序模型</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_6_interview/index.html">7. 面试经验</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_6_interview/1.machine_learning.html">7.1. 机器学习相关</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_6_interview/2.recommender.html">7.2. 推荐模型相关</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_6_interview/3.trends.html">7.3. 热门技术相关</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_6_interview/4.product.html">7.4. 业务场景相关</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_6_interview/5.hr_other.html">7.5. HR及其他</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_appendix/index.html">8. Appendix</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_appendix/word2vec.html">8.1. Word2vec</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_references/references.html">参考文献</a></li>
</ul>

            </nav>
        
        </div>
    
</header>
        <main class="mdl-layout__content" tabIndex="0">

	<script type="text/javascript" src="../../_static/sphinx_materialdesign_theme.js "></script>
    <header class="mdl-layout__drawer">
    
          <!-- Title -->
      <span class="mdl-layout-title">
          <a class="title" href="../../index.html">
              <span class="title-text">
                  FunRec 推荐系统
              </span>
          </a>
      </span>
    
    
      <div class="globaltoc">
        <span class="mdl-layout-title toc">Table Of Contents</span>
        
        
            
            <nav class="mdl-navigation">
                <ul>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_preface/index.html">前言</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_installation/index.html">安装</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_notation/index.html">符号</a></li>
</ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../chapter_0_introduction/index.html">1. 推荐系统概述</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_0_introduction/1.intro.html">1.1. 推荐系统是什么？</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_0_introduction/2.outline.html">1.2. 本书概览</a></li>
</ul>
</li>
<li class="toctree-l1 current"><a class="reference internal" href="../index.html">2. 召回模型</a><ul class="current">
<li class="toctree-l2 current"><a class="reference internal" href="index.html">2.1. 协同过滤</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="1.usercf.html">2.1.1. 基于用户的协同过滤</a></li>
<li class="toctree-l3"><a class="reference internal" href="2.itemcf.html">2.1.2. 基于物品的协同过滤</a></li>
<li class="toctree-l3"><a class="reference internal" href="3.swing.html">2.1.3. Swing 算法</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">2.1.4. 矩阵分解</a></li>
<li class="toctree-l3"><a class="reference internal" href="5.summary.html">2.1.5. 总结</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../2.embedding/index.html">2.2. 向量召回</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../2.embedding/1.i2i.html">2.2.1. I2I召回</a></li>
<li class="toctree-l3"><a class="reference internal" href="../2.embedding/2.u2i.html">2.2.2. U2I召回</a></li>
<li class="toctree-l3"><a class="reference internal" href="../2.embedding/3.summary.html">2.2.3. 总结</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../3.sequence/index.html">2.3. 序列召回</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../3.sequence/1.user_interests.html">2.3.1. 深化用户兴趣表示</a></li>
<li class="toctree-l3"><a class="reference internal" href="../3.sequence/2.generateive_recall.html">2.3.2. 生成式召回方法</a></li>
<li class="toctree-l3"><a class="reference internal" href="../3.sequence/3.summary.html">2.3.3. 总结</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_2_ranking/index.html">3. 精排模型</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_2_ranking/1.wide_and_deep.html">3.1. 记忆与泛化</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_2_ranking/2.feature_crossing/index.html">3.2. 特征交叉</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/2.feature_crossing/1.second_order.html">3.2.1. 二阶特征交叉</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/2.feature_crossing/2.higher_order.html">3.2.2. 高阶特征交叉</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/2.feature_crossing/3.summary.html">3.2.3. 总结</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_2_ranking/3.sequence.html">3.3. 序列建模</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_2_ranking/4.multi_objective/index.html">3.4. 多目标建模</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/4.multi_objective/1.arch.html">3.4.1. 基础结构演进</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/4.multi_objective/2.dependency_modeling.html">3.4.2. 任务依赖建模</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/4.multi_objective/3.multi_loss_optim.html">3.4.3. 多目标损失融合</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/4.multi_objective/4.summary.html">3.4.4. 小结</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_2_ranking/5.multi_scenario/index.html">3.5. 多场景建模</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/5.multi_scenario/1.multi_tower.html">3.5.1. 多塔结构</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/5.multi_scenario/2.dynamic_weight.html">3.5.2. 动态权重建模</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../chapter_2_ranking/5.multi_scenario/3.summary.html">3.5.3. 小结</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_3_rerank/index.html">4. 重排模型</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_3_rerank/1.greedy.html">4.1. 基于贪心的重排</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_3_rerank/2.personalized.html">4.2. 基于个性化的重排</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_3_rerank/3.summary.html">4.3. 本章小结</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_4_trends/index.html">5. 难点及热点研究</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_4_trends/1.debias.html">5.1. 模型去偏</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_4_trends/2.cold_start.html">5.2. 冷启动问题</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_4_trends/3.generative.html">5.3. 生成式推荐</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_4_trends/4.summary.html">5.4. 本章小结</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_5_projects/index.html">6. 项目实践</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_5_projects/1.understanding.html">6.1. 赛题理解</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_5_projects/2.baseline.html">6.2. Baseline</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_5_projects/3.analysis.html">6.3. 数据分析</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_5_projects/4.recall.html">6.4. 多路召回</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_5_projects/5.feature_engineering.html">6.5. 特征工程</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_5_projects/6.ranking.html">6.6. 排序模型</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_6_interview/index.html">7. 面试经验</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_6_interview/1.machine_learning.html">7.1. 机器学习相关</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_6_interview/2.recommender.html">7.2. 推荐模型相关</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_6_interview/3.trends.html">7.3. 热门技术相关</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_6_interview/4.product.html">7.4. 业务场景相关</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_6_interview/5.hr_other.html">7.5. HR及其他</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_appendix/index.html">8. Appendix</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../chapter_appendix/word2vec.html">8.1. Word2vec</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../chapter_references/references.html">参考文献</a></li>
</ul>

            </nav>
        
        </div>
    
</header>

    <div class="document">
        <div class="page-content" role="main">
        
  <section id="matrix-factorization">
<span id="id1"></span><h1><span class="section-number">2.1.4. </span>矩阵分解<a class="headerlink" href="#matrix-factorization" title="Permalink to this heading">¶</a></h1>
<p>在推荐系统中，我们经常观察到这样的规律：喜欢《理智与情感》的用户往往也会给《公主日记》好评，而钟爱《致命武器》的观众通常也喜欢《独立日》。这反映了用户偏好的内在结构——一些隐含的“品味因子”在起作用。比如有些用户偏好面向女性的影片，有些则更喜欢面向男性的内容；有些人倾向于严肃深刻的作品如《阿马迪斯》，有些人则更享受轻松娱乐的片子如《阿呆与阿瓜》。</p>
<p>在前面的章节中，我们了解了UserCF和ItemCF这些基于邻域的协同过滤方法。它们的思路很直观：通过寻找相似的用户或物品来进行推荐，就像
<a class="reference internal" href="#mf-usercf-illustration"><span class="std std-numref">图2.1.6</span></a> 展示的那样。</p>
<figure class="align-default" id="id5">
<span id="mf-usercf-illustration"></span><a class="reference internal image-reference" href="../../_images/mf_usercf_illustration.svg"><img alt="../../_images/mf_usercf_illustration.svg" src="../../_images/mf_usercf_illustration.svg" width="350px" /></a>
<figcaption>
<p><span class="caption-number">图2.1.6 </span><span class="caption-text">基于用户行为统计的方法。张三喜欢左边的三部电影。为了对他进行预测，系统会找到也喜欢这些电影的相似用户，然后确定他们还喜欢哪些其他电影。在这种情况下，所有三位用户都喜欢《拯救大兵瑞恩》，因此这是首个推荐。接着，其中两位用户喜欢《沙丘》，所以它排在第二位，依此类推。</span><a class="headerlink" href="#id5" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<p>但这种方法有个致命弱点：当评分数据非常稀疏时，很难找到足够的相似用户或物品。想想看，在一个有百万用户和十万电影的系统中，大部分用户只看过其中几十部电影，传统方法很可能因为共同评分太少而失效。</p>
<p>这时候，矩阵分解登场了。它不再直接寻找相似性，而是换了个思路：假设用户的偏好和电影的特征都可以用几个关键因子来描述。比如，我们可以用“面向男性vs面向女性”和“严肃vs逃避现实”这两个维度来刻画电影，同时用用户对这两类特征的偏好程度来描述用户。这样，预测一个用户对某部电影的评分就变成了计算这两个向量的相似度。</p>
<p>矩阵分解的核心想法建立在两个关键假设上：</p>
<ul class="simple">
<li><p>第一个是低秩假设：虽然评分矩阵看起来很复杂，但实际上可能只受少数几个隐含因素影响，比如“面向男性vs面向女性”、“严肃vs逃避现实”等维度。</p></li>
<li><p>第二个是隐向量假设：每个用户和每部电影都能用一个包含这些隐含因子的向量来表示，用户向量反映了其对各种因子的偏好程度，而电影向量则描述了该电影在各个因子上的特征强度。</p></li>
</ul>
<p>这种做法的好处是显而易见的：即使两个用户没有看过相同的电影，只要他们在隐含因子上表现相似，我们就能为他们推荐相似的内容。这大大提高了模型处理稀疏数据的能力。</p>
<figure class="align-default" id="id6">
<span id="mf-illustration"></span><a class="reference internal image-reference" href="../../_images/mf_illustration.svg"><img alt="../../_images/mf_illustration.svg" src="../../_images/mf_illustration.svg" width="400px" /></a>
<figcaption>
<p><span class="caption-number">图2.1.7 </span><span class="caption-text">隐语义模型意图，该方法通过两个维度来刻画用户和电影：一个是面向男性与面向女性，另一个是严肃与逃避现实。</span><a class="headerlink" href="#id6" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<p>接下来我们看看如何把这个想法变成具体的算法。我们将介绍两种矩阵分解模型：简单直接的<strong>基础模型</strong>（FunkSVD）和考虑评分偏差的<strong>改进模型</strong>（BiasSVD）。</p>
<section id="funksvd">
<h2><span class="section-number">2.1.4.1. </span>FunkSVD: 基础模型<a class="headerlink" href="#funksvd" title="Permalink to this heading">¶</a></h2>
<p>FunkSVD 由 Simon Funk 在2006年提出
<span id="id2">(<a class="reference internal" href="../../chapter_references/references.html#id10" title="Funk, S. (2006). Netflix update: try this at home. Blog. URL: https://sifter.org/simon/journal/20061211.html">Funk, 2006</a>)</span>，是矩阵分解家族中最容易理解的一个。它的想法非常直接：把复杂的用户-物品评分矩阵分解成两个简单的矩阵——用户特征矩阵和物品特征矩阵。</p>
<p>假设我们有<span class="math notranslate nohighlight">\(m\)</span>个用户和<span class="math notranslate nohighlight">\(n\)</span>个物品，想要用<span class="math notranslate nohighlight">\(K\)</span>个隐含因子来描述它们。那么用户<span class="math notranslate nohighlight">\(u\)</span>可以用一个<span class="math notranslate nohighlight">\(K\)</span>维向量<span class="math notranslate nohighlight">\(p_u\)</span>来表示，物品<span class="math notranslate nohighlight">\(i\)</span>也可以用一个<span class="math notranslate nohighlight">\(K\)</span>维向量<span class="math notranslate nohighlight">\(q_i\)</span>来表示。预测用户<span class="math notranslate nohighlight">\(u\)</span>对物品<span class="math notranslate nohighlight">\(i\)</span>的评分就是这两个向量的内积：</p>
<div class="math notranslate nohighlight" id="equation-chapter-1-retrieval-1-cf-4-mf-0">
<span class="eqno">(2.1.20)<a class="headerlink" href="#equation-chapter-1-retrieval-1-cf-4-mf-0" title="Permalink to this equation">¶</a></span>\[\hat{r}_{ui} = p_u^T q_i = \sum_{k=1}^{K} p_{u,k} \cdot q_{i,k}\]</div>
<p>这里<span class="math notranslate nohighlight">\(p_{u,k}\)</span>表示用户<span class="math notranslate nohighlight">\(u\)</span>在第<span class="math notranslate nohighlight">\(k\)</span>个隐含因子上的偏好程度，<span class="math notranslate nohighlight">\(q_{i,k}\)</span>表示物品<span class="math notranslate nohighlight">\(i\)</span>在第<span class="math notranslate nohighlight">\(k\)</span>个隐含因子上的特征强度。</p>
<p>现在问题变成了：如何找到这些隐含因子？我们采用一个很自然的思路——让预测评分尽可能接近真实评分。具体来说，我们要最小化所有已知评分的预测误差：</p>
<div class="math notranslate nohighlight" id="equation-chapter-1-retrieval-1-cf-4-mf-1">
<span class="eqno">(2.1.21)<a class="headerlink" href="#equation-chapter-1-retrieval-1-cf-4-mf-1" title="Permalink to this equation">¶</a></span>\[\min_{P,Q} \frac{1}{2} \sum_{(u,i)\in \mathcal{K}} \left( r_{ui} - p_u^T q_i \right)^2\]</div>
<p>这里<span class="math notranslate nohighlight">\(\mathcal{K}\)</span>表示所有已知评分的用户-物品对，<span class="math notranslate nohighlight">\(r_{ui}\)</span>是用户<span class="math notranslate nohighlight">\(u\)</span>对物品<span class="math notranslate nohighlight">\(i\)</span>的真实评分。</p>
<p>要解决这个优化问题，我们使用梯度下降法。对于每个观测到的评分，我们先计算预测误差<span class="math notranslate nohighlight">\(e_{ui} = r_{ui} - p_u^T q_i\)</span>，然后沿着误差减小的方向更新参数：</p>
<div class="math notranslate nohighlight" id="equation-chapter-1-retrieval-1-cf-4-mf-2">
<span class="eqno">(2.1.22)<a class="headerlink" href="#equation-chapter-1-retrieval-1-cf-4-mf-2" title="Permalink to this equation">¶</a></span>\[p_{u,k} \leftarrow p_{u,k} + \eta \cdot e_{ui} \cdot q_{i,k}\]</div>
<div class="math notranslate nohighlight" id="equation-chapter-1-retrieval-1-cf-4-mf-3">
<span class="eqno">(2.1.23)<a class="headerlink" href="#equation-chapter-1-retrieval-1-cf-4-mf-3" title="Permalink to this equation">¶</a></span>\[q_{i,k} \leftarrow q_{i,k} + \eta \cdot e_{ui} \cdot p_{u,k}\]</div>
<p>其中<span class="math notranslate nohighlight">\(\eta\)</span>是学习率，控制每次更新的步长。这个更新规则的直觉很简单：如果预测评分偏低了（<span class="math notranslate nohighlight">\(e_{ui} &gt; 0\)</span>），我们就增大相关的参数值；如果预测偏高了，就减小参数值。</p>
<p>不过在实际应用中，我们通常还会加入L2正则化来防止过拟合：</p>
<div class="math notranslate nohighlight" id="equation-chapter-1-retrieval-1-cf-4-mf-4">
<span class="eqno">(2.1.24)<a class="headerlink" href="#equation-chapter-1-retrieval-1-cf-4-mf-4" title="Permalink to this equation">¶</a></span>\[\min_{P,Q} \frac{1}{2} \sum_{(u,i)\in \mathcal{K}} \left( r_{ui} - p_u^T q_i \right)^2 + \lambda \left( \|p_u\|^2 + \|q_i\|^2 \right)\]</div>
<p>这样可以避免模型过度拟合训练数据，提高在新数据上的表现。</p>
</section>
<section id="biassvd">
<h2><span class="section-number">2.1.4.2. </span>BiasSVD: 改进模型<a class="headerlink" href="#biassvd" title="Permalink to this heading">¶</a></h2>
<p>基础模型虽然简洁，但在实际使用中我们发现了一个问题：不同用户的评分习惯差异很大。有些用户天生就是“好人”，很少给低分；有些用户则比较严格，平均分都不高。同样，有些电影因为制作精良或者明星云集，普遍得到较高评分；而有些冷门或质量一般的电影则评分偏低。</p>
<p>这些系统性的偏差如果不处理，会影响推荐的准确性。BiasSVD
<span id="id3">(<a class="reference internal" href="../../chapter_references/references.html#id11" title="Koren, Y., Bell, R., &amp; Volinsky, C. (2009). Matrix factorization techniques for recommender systems. Computer, 42(8), 30–37.">Koren <em>et al.</em>, 2009</a>)</span>
正是为了解决这个问题而提出的。它在基础模型的基础上引入了偏置项，让预测公式变成：</p>
<div class="math notranslate nohighlight" id="equation-chapter-1-retrieval-1-cf-4-mf-5">
<span class="eqno">(2.1.25)<a class="headerlink" href="#equation-chapter-1-retrieval-1-cf-4-mf-5" title="Permalink to this equation">¶</a></span>\[\hat{r}_{ui} = \mu + b_u + b_i + p_u^T q_i\]</div>
<p>这里新增了三个项：<span class="math notranslate nohighlight">\(\mu\)</span>是所有评分的全局平均值，反映了整个系统的评分水平；<span class="math notranslate nohighlight">\(b_u\)</span>是用户<span class="math notranslate nohighlight">\(u\)</span>的个人偏置，反映了该用户相对于平均水平是倾向于给高分还是低分；<span class="math notranslate nohighlight">\(b_i\)</span>是物品<span class="math notranslate nohighlight">\(i\)</span>的偏置，反映了该物品相对于平均水平是受欢迎还是不受欢迎。</p>
<p>相应地，优化目标也要调整：</p>
<div class="math notranslate nohighlight" id="equation-chapter-1-retrieval-1-cf-4-mf-6">
<span class="eqno">(2.1.26)<a class="headerlink" href="#equation-chapter-1-retrieval-1-cf-4-mf-6" title="Permalink to this equation">¶</a></span>\[\min_{P,Q,b_u,b_i} \frac{1}{2} \sum_{(u,i)\in \mathcal{K}} \left( r_{ui} - \mu - b_u - b_i - p_u^T q_i \right)^2 + \lambda \left( \|p_u\|^2 + \|q_i\|^2 + b_u^2 + b_i^2 \right)\]</div>
<p>在参数更新时，除了用户和物品的隐向量，我们还需要更新偏置项：</p>
<div class="math notranslate nohighlight" id="equation-chapter-1-retrieval-1-cf-4-mf-7">
<span class="eqno">(2.1.27)<a class="headerlink" href="#equation-chapter-1-retrieval-1-cf-4-mf-7" title="Permalink to this equation">¶</a></span>\[b_u \leftarrow b_u + \eta \left( e_{ui} - \lambda b_u \right)\]</div>
<div class="math notranslate nohighlight" id="equation-chapter-1-retrieval-1-cf-4-mf-8">
<span class="eqno">(2.1.28)<a class="headerlink" href="#equation-chapter-1-retrieval-1-cf-4-mf-8" title="Permalink to this equation">¶</a></span>\[b_i \leftarrow b_i + \eta \left( e_{ui} - \lambda b_i \right)\]</div>
<p>这种改进看似简单，但效果显著。通过分离出系统性偏差，模型能够更准确地捕捉用户和物品之间的真实交互模式，从而提供更精准的推荐。</p>
</section>
<section id="id4">
<h2><span class="section-number">2.1.4.3. </span>代码实践<a class="headerlink" href="#id4" title="Permalink to this heading">¶</a></h2>
<p>FunkSVD 在 MovieLens 数据集上的应用</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">sys</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">funrec</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">funrec.utils</span><span class="w"> </span><span class="kn">import</span> <span class="n">build_metrics_table</span>

<span class="c1"># 加载配置</span>
<span class="n">config</span> <span class="o">=</span> <span class="n">funrec</span><span class="o">.</span><span class="n">load_config</span><span class="p">(</span><span class="s1">&#39;funksvd&#39;</span><span class="p">)</span>

<span class="c1"># 加载数据</span>
<span class="n">train_data</span><span class="p">,</span> <span class="n">test_data</span> <span class="o">=</span> <span class="n">funrec</span><span class="o">.</span><span class="n">load_data</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>

<span class="c1"># 准备特征</span>
<span class="n">feature_columns</span><span class="p">,</span> <span class="n">processed_data</span> <span class="o">=</span> <span class="n">funrec</span><span class="o">.</span><span class="n">prepare_features</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">features</span><span class="p">,</span> <span class="n">train_data</span><span class="p">,</span> <span class="n">test_data</span><span class="p">)</span>

<span class="c1"># 训练模型</span>
<span class="n">models</span> <span class="o">=</span> <span class="n">funrec</span><span class="o">.</span><span class="n">train_model</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">training</span><span class="p">,</span> <span class="n">feature_columns</span><span class="p">,</span> <span class="n">processed_data</span><span class="p">)</span>

<span class="c1"># 评估模型</span>
<span class="n">metrics</span> <span class="o">=</span> <span class="n">funrec</span><span class="o">.</span><span class="n">evaluate_model</span><span class="p">(</span><span class="n">models</span><span class="p">,</span> <span class="n">processed_data</span><span class="p">,</span> <span class="n">config</span><span class="o">.</span><span class="n">evaluation</span><span class="p">,</span> <span class="n">feature_columns</span><span class="p">)</span>

<span class="nb">print</span><span class="p">(</span><span class="n">build_metrics_table</span><span class="p">(</span><span class="n">metrics</span><span class="p">))</span>
</pre></div>
</div>
<div class="output highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">+---------------+--------------+-----------+----------+----------------+---------------+</span>
<span class="o">|</span>   <span class="n">hit_rate</span><span class="o">@</span><span class="mi">10</span> <span class="o">|</span>   <span class="n">hit_rate</span><span class="o">@</span><span class="mi">5</span> <span class="o">|</span>   <span class="n">ndcg</span><span class="o">@</span><span class="mi">10</span> <span class="o">|</span>   <span class="n">ndcg</span><span class="o">@</span><span class="mi">5</span> <span class="o">|</span>   <span class="n">precision</span><span class="o">@</span><span class="mi">10</span> <span class="o">|</span>   <span class="n">precision</span><span class="o">@</span><span class="mi">5</span> <span class="o">|</span>
<span class="o">+===============+==============+===========+==========+================+===============+</span>
<span class="o">|</span>             <span class="mi">0</span> <span class="o">|</span>            <span class="mi">0</span> <span class="o">|</span>         <span class="mi">0</span> <span class="o">|</span>        <span class="mi">0</span> <span class="o">|</span>              <span class="mi">0</span> <span class="o">|</span>             <span class="mi">0</span> <span class="o">|</span>
<span class="o">+---------------+--------------+-----------+----------+----------------+---------------+</span>
</pre></div>
</div>
<p>BiasSVD 在 MovieLens 数据集上的应用</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">config</span> <span class="o">=</span> <span class="n">funrec</span><span class="o">.</span><span class="n">load_config</span><span class="p">(</span><span class="s1">&#39;biassvd&#39;</span><span class="p">)</span>

<span class="c1"># 加载数据</span>
<span class="n">train_data</span><span class="p">,</span> <span class="n">test_data</span> <span class="o">=</span> <span class="n">funrec</span><span class="o">.</span><span class="n">load_data</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>

<span class="c1"># 准备特征</span>
<span class="n">feature_columns</span><span class="p">,</span> <span class="n">processed_data</span> <span class="o">=</span> <span class="n">funrec</span><span class="o">.</span><span class="n">prepare_features</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">features</span><span class="p">,</span> <span class="n">train_data</span><span class="p">,</span> <span class="n">test_data</span><span class="p">)</span>

<span class="c1"># 训练模型</span>
<span class="n">models</span> <span class="o">=</span> <span class="n">funrec</span><span class="o">.</span><span class="n">train_model</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">training</span><span class="p">,</span> <span class="n">feature_columns</span><span class="p">,</span> <span class="n">processed_data</span><span class="p">)</span>

<span class="c1"># 评估模型</span>
<span class="n">metrics</span> <span class="o">=</span> <span class="n">funrec</span><span class="o">.</span><span class="n">evaluate_model</span><span class="p">(</span><span class="n">models</span><span class="p">,</span> <span class="n">processed_data</span><span class="p">,</span> <span class="n">config</span><span class="o">.</span><span class="n">evaluation</span><span class="p">,</span> <span class="n">feature_columns</span><span class="p">)</span>

<span class="nb">print</span><span class="p">(</span><span class="n">build_metrics_table</span><span class="p">(</span><span class="n">metrics</span><span class="p">))</span>
</pre></div>
</div>
<div class="output highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">+---------------+--------------+-----------+----------+----------------+---------------+</span>
<span class="o">|</span>   <span class="n">hit_rate</span><span class="o">@</span><span class="mi">10</span> <span class="o">|</span>   <span class="n">hit_rate</span><span class="o">@</span><span class="mi">5</span> <span class="o">|</span>   <span class="n">ndcg</span><span class="o">@</span><span class="mi">10</span> <span class="o">|</span>   <span class="n">ndcg</span><span class="o">@</span><span class="mi">5</span> <span class="o">|</span>   <span class="n">precision</span><span class="o">@</span><span class="mi">10</span> <span class="o">|</span>   <span class="n">precision</span><span class="o">@</span><span class="mi">5</span> <span class="o">|</span>
<span class="o">+===============+==============+===========+==========+================+===============+</span>
<span class="o">|</span>        <span class="mf">0.0008</span> <span class="o">|</span>       <span class="mf">0.0008</span> <span class="o">|</span>    <span class="mf">0.0008</span> <span class="o">|</span>   <span class="mf">0.0008</span> <span class="o">|</span>         <span class="mf">0.0001</span> <span class="o">|</span>        <span class="mf">0.0002</span> <span class="o">|</span>
<span class="o">+---------------+--------------+-----------+----------+----------------+---------------+</span>
</pre></div>
</div>
</section>
</section>


        </div>
        <div class="side-doc-outline">
            <div class="side-doc-outline--content"> 
<div class="localtoc">
    <p class="caption">
      <span class="caption-text">Table Of Contents</span>
    </p>
    <ul>
<li><a class="reference internal" href="#">2.1.4. 矩阵分解</a><ul>
<li><a class="reference internal" href="#funksvd">2.1.4.1. FunkSVD: 基础模型</a></li>
<li><a class="reference internal" href="#biassvd">2.1.4.2. BiasSVD: 改进模型</a></li>
<li><a class="reference internal" href="#id4">2.1.4.3. 代码实践</a></li>
</ul>
</li>
</ul>

</div>
            </div>
        </div>

      <div class="clearer"></div>
    </div><div class="pagenation">
     <a id="button-prev" href="3.swing.html" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--colored" role="botton" accesskey="P">
         <i class="pagenation-arrow-L fas fa-arrow-left fa-lg"></i>
         <div class="pagenation-text">
            <span class="pagenation-direction">Previous</span>
            <div>2.1.3. Swing 算法</div>
         </div>
     </a>
     <a id="button-next" href="5.summary.html" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--colored" role="botton" accesskey="N">
         <i class="pagenation-arrow-R fas fa-arrow-right fa-lg"></i>
        <div class="pagenation-text">
            <span class="pagenation-direction">Next</span>
            <div>2.1.5. 总结</div>
        </div>
     </a>
  </div>
        
        </main>
    </div>
  </body>
</html>